package com.qf.mybatisplus.utils;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.SecureRandom;

/**
* @Description: DES加解密（CBC加密）
* @Author: Chen
* @Date: 2020/11/25
*/
public class DesCbcUtil {

    public static void main(String[] args) {
        String enc = "";
        String dec = "";

        String str = "AvHLfKoZJDgJKdXIHNQ+l9uaULAjwW6s47pKCK8//bNQHLpnik90TTh26a4mCdq2NrK3c89Lz835S/4BKkGf6sc8vTmocuWogDEl+BToha9et19ZJMS6FZm9vA4H59Imqb8NU2sSeciXeDo6s3SZIRKxUjpwRW0HNdBxi5zHmmE3Fk2QGH/vV3EGoQ7A95ACV3HnTmoHSKPe5K7eHKOoxa1KWm8r9YhQDyHwv/drGc8Z27I0Y3/nVLnjZRIZaChV9WGnYcVdNIThNS7kvkixLf+HQVKv2olcEXvNTPXLrsAlQKYMqOkewTDEYsLBZBYt6gRwLEBsYP3YKw4zWu5MmKbR1T4w+DZ0ojUu7dgZY4SsfRQLHOoKZgPDLaNgDYhhWlTlNUVeloyQ7myKXnku4851QPCWIpW8vRlfeV6oBTYhUTfFx7WwtCIdNyIgNbqKqvwJHcKBA4Trl0qKWnlvSbZo4CF1UT8C0Meykvy0jSs04HXOPgofo9Khiwsl6J8YG+DUJItq97dX+OffkYtgwGAFHu5GusS28W3kLmtAHiID9OITK1CUvg2T0OV8eaVivJqxWjGISC61TaE8uJ7OdjmdwYe34S6/y8TndDzlPx4n11l5n7GwQ/AYJh/Si22+sw4ArC3QCw1Ls4TPbJwMBVzA4kjKZJnSq1HPFMsT2J5fu0RZd7RpW8NuWHvHXfz2Lh4LQAk3iQg04fzrEPLxVz6L63ravmn6Oz0VQ0dkmV95alFO4H5d2fpjF9d41wovYeKQurlwWLWOKhc39zOYnBSp3HmFjc9W0+Cyh0tPkRS2KfcMeI3tbDWci/0UGfuZhE+5+BHhY8LoHnVWP7cVck8Uk5URfpFXoWxEgAJf3k1oKtoJEy+i0iacV6vgzIMX4iEhGq9nYmSIdj+zmQ7fVSXSAdn5cfNYZ72MyMXU7r1/TXN7Ekh9JvCbkUauXHN6Jlp6v2VxLK3AQn3p4b+jx6bCroI0GoG+UbRaULv9ZZHaJ8MCq+mOjYhfuHeF8dFZaAPEptI8mBKAzeTraKtg5b3Xqcop0FCrhyGtTUycyZLjm4i6Xc7G9TSDtqwmJ9Z/7qOtKrU4gxobUyKbjrPQoN6WGfUE6Rm6zZeRjS5xPHkakSNkNzTvsx/r7kKo/aw+/r1Dd2CkU+qvh6eOoQzBkawWkO3uRxKgn0wiXCG6WBfaY5YPQLiGopIwfv8qSCDS5assaHQN4zj74JJsxKTOYScOpMAJOzHMXE3u987RTa4179M0Ht6lAWYerGB7PTpkwi8ENhIDJTuxsKYpvGeelkatSnNK0Y4cGvkp+iRJGSSD1qQ2oy8mSDGo2Sji4ftKU0HEeXP65hklSSra069EO1DhXmUD8YJFZ8JY1eLi/3brgQrYU2fC9wQ/cnMqymJltJDyfdCTo/KeYVT5KMdxDz1siXfcmATq\n";

        try {
            enc = wxEcrypt("{\"Type\":\"GRZFZM\",\"Qlrmc\":\"周锡慧\",\"Qlrzjhm\":\"320205199112140023\"}", "ZTBDGGPT", "GB2312");
            dec = wxDecrypt(str, "ZTBDGGPT", "GB2312");
        } catch (Exception e) {
            System.out.println(e.toString());
        }
//        System.out.println(enc);
//        System.out.println("84ITlgTJDvLnzySeeBLGbujbFZ3B2PZJCtPjxrvZrkM+YJeHd4hHBID9HxBSd4YyyHyro5MKGmg18P+uH6UB8KYPBQouS+T+");
        System.out.println(dec);
    }

    /**
     * 偏移变量
     */
    private static byte[] IV = {0x12, 0x34, 0x56, 0x78, (byte) 0x90,
            (byte) 0xAB, (byte) 0xCD, (byte) 0xEF};
    /**
     * 密钥算法
     */
    private static final String ALGORITHM = "DES";
    /**
     * 加密/解密算法-工作模式-填充模式
     */
    private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";
    /**
     * 默认编码
     */
    private static final String CHARSET = "UTF-8";

    /**
     * 加密
     *
     * @param data 待加密的明文
     * @param key  加密密钥
     * @return 密文
     * @throws Exception
     */
    public static String encrypt(String data, String key) throws Exception {
        if (StringUtils.isSpace(data) || StringUtils.isSpace(key)) {
            return "";
        }
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(CHARSET));
        SecretKeyFactory skf = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey sk = skf.generateSecret(desKeySpec);
        Cipher cip = Cipher.getInstance(CIPHER_ALGORITHM);// Cipher.getInstance(ALGORITHM);
//        IvParameterSpec ivSpec = new IvParameterSpec(IV);
        IvParameterSpec ivSpec = new IvParameterSpec(key.getBytes(CHARSET));

        cip.init(Cipher.ENCRYPT_MODE, sk, ivSpec);// IV的方式
        // cip.init(Cipher.ENCRYPT_MODE, sk, sr);//没有传递IV

//        return new String(new BASE64Encoder().encode(cip.doFinal(data.getBytes("GB2312")))); // BASE64Encoder加密后会导致字符串换行
        return new String(new Base64().encode(cip.doFinal(data.getBytes("GB2312"))));
    }

    /**
     * 解密
     *
     * @param data 待解密的密文
     * @param key  解密密钥
     * @return 明文
     * @throws Exception
     */
    public static String decrypt(String data, String key) throws Exception {
        if (StringUtils.isSpace(data) || StringUtils.isSpace(key)) {
            return "";
        }

        byte[] buf = new Base64().decode(data.getBytes(CHARSET));
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(CHARSET));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKeySpec);
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");// Cipher.getInstance(ALGORITHM);
//        IvParameterSpec ivSpec = new IvParameterSpec(IV);
        IvParameterSpec ivSpec = new IvParameterSpec(key.getBytes(CHARSET));
        cipher.init(Cipher.DECRYPT_MODE, securekey, ivSpec);

        SecureRandom sr = new SecureRandom();
        // cipher.init(Cipher.DECRYPT_MODE, securekey, sr);//没有传递IV
        buf = cipher.doFinal(buf);
        return new String(buf, "GB2312");

//        return new String(cipher.doFinal(buf), CHARSET);
    }

    /**
     *
     * @param data 待加密的明文
     * @param key  加密密钥
     * @param wxCharset 无锡第三方数据编码格式
     * @return 加密后的密文
     * @throws Exception
     */
    public static String wxEcrypt(String data, String key, String wxCharset) throws Exception {
//        String wxCharset = "GB2312";
        if (StringUtils.isSpace(data) || StringUtils.isSpace(key)) {
            return "";
        }
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(CHARSET));
        SecretKeyFactory skf = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey sk = skf.generateSecret(desKeySpec);
        Cipher cip = Cipher.getInstance(CIPHER_ALGORITHM);// Cipher.getInstance("DES");
        IvParameterSpec ivSpec = new IvParameterSpec(key.getBytes(CHARSET));
        cip.init(Cipher.ENCRYPT_MODE, sk, ivSpec);// IV的方式
        return new String(new Base64().encode(cip.doFinal(data.getBytes(wxCharset))));
    }

    /**
     *
     * @param data 待解密的密文
     * @param key  解密的秘钥
     * @param wxCharset 无锡第三方数据编码格式
     * @return 解密后的明文
     * @throws Exception
     */
    public static String wxDecrypt(String data, String key, String wxCharset) throws Exception {
//        String wxCharset = "GB2312";
        if (StringUtils.isSpace(data) || StringUtils.isSpace(key)) {
            return "";
        }

        byte[] buf = new Base64().decode(data.getBytes(CHARSET));
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(CHARSET));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(desKeySpec);
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        IvParameterSpec ivSpec = new IvParameterSpec(key.getBytes(CHARSET));
        cipher.init(Cipher.DECRYPT_MODE, securekey, ivSpec);

        SecureRandom sr = new SecureRandom();
        buf = cipher.doFinal(buf);
        return new String(buf, wxCharset);
    }

}
